package org.iabako.shared.querydefinition;

import org.iabako.shared.querydefinition.columndefinition.*;
import org.iabako.shared.tools.GenericTools;

import java.beans.Transient;
import java.util.ArrayList;
import java.util.List;

/**
 * TODO javadoc
 * Date: 24/11/13
 * Time: 18:22
 */
public enum SearchMotorQueryEnum {

    ClientSearch("from Client client", null, null, "client", "client", ClientColumnEnum.name, "group by client.id", "client_search_export_file_name",
            ClientColumnEnum.number, ClientColumnEnum.gender, ClientColumnEnum.name, ClientColumnEnum.email, ClientColumnEnum.birthday,
            ClientColumnEnum.address1, ClientColumnEnum.address2, ClientColumnEnum.addressCity,
            ClientColumnEnum.phoneNumber1, ClientColumnEnum.phoneNumber2, ClientColumnEnum.status, ClientColumnEnum.disabled),

    ClientConversationSearch("from ClientConversation conversation", null, null, "conversation", "conversation",
            ClientConversationColumnEnum.orderByStatusAndDate, "group by conversation.id", null,
            ClientConversationColumnEnum.type, ClientConversationColumnEnum.date,
            ClientConversationColumnEnum.interlocutor, ClientConversationColumnEnum.subject,
            ClientConversationColumnEnum.body, ClientConversationColumnEnum.status, ClientConversationColumnEnum.automatic),

    ProductSearch("from Product product", null, null, "product", "product",
            ProductColumnEnum.number, "group by product.id", "product_search_export_file_name",
            ProductColumnEnum.number, ProductColumnEnum.name, ProductColumnEnum.description,
            ProductColumnEnum.purchasePrice, ProductColumnEnum.price, ProductColumnEnum.tax,
            ProductColumnEnum.quantity, ProductColumnEnum.unit),

    StockSearch("from Product product", null, null, "product", "product",
            ProductColumnEnum.number, "group by product.id", "product_search_export_file_name",
            ProductColumnEnum.number, ProductColumnEnum.name, ProductColumnEnum.purchasePrice, ProductColumnEnum.price,
            ProductColumnEnum.quantityNow, ProductColumnEnum.unit, ProductColumnEnum.quantityModification, ProductColumnEnum.newQuantity),

    ServiceSearch("from Service service", null, null, "service", "service",
            ServiceColumnEnum.number, "group by service.id", "service_search_export_file_name",
            ServiceColumnEnum.number, ServiceColumnEnum.name, ServiceColumnEnum.description, ServiceColumnEnum.price, ServiceColumnEnum.tax),

    //We add "left outer join sale.client client" in selectQueryFromFilter because client could be a criteria in where clause
    QuoteSearch("from Sale sale", "left outer join sale.client client", null,
            "sale", "sale", SaleColumnEnum.dateLastModification, "group by sale.id", "quote_search_export_file_name",
            SaleColumnEnum.saleNumberForQuote, SaleColumnEnum.productsServices, SaleColumnEnum.clientNumber, SaleColumnEnum.client, SaleColumnEnum.quoteDate,
            SaleColumnEnum.price, SaleColumnEnum.status),

    //We add "left outer join sale.client client" in selectQueryFromFilter because client could be a criteria in where clause
    SaleSearch("from Sale sale", "left outer join sale.client client", null,
            "sale", "sale", SaleColumnEnum.dateLastModification, "group by sale.id", "sale_search_export_file_name",
            SaleColumnEnum.saleNumber, SaleColumnEnum.productsServices, SaleColumnEnum.clientNumber, SaleColumnEnum.client, SaleColumnEnum.date,
            SaleColumnEnum.payed, SaleColumnEnum.receivable, SaleColumnEnum.price, SaleColumnEnum.status),

    //We add "left outer join sale.client client" in selectQueryFromFilter because client could be a criteria in where clause
    PastInstallmentSearch("from Installment installment", "join installment.sale sale join sale.client client", null,
            "installment", "sale", PastInstallmentColumnEnum.date, "group by installment.id", "past_installments_search_export_file_name",
            PastInstallmentColumnEnum.clientNumber, PastInstallmentColumnEnum.client, PastInstallmentColumnEnum.productsServices,
            PastInstallmentColumnEnum.date, PastInstallmentColumnEnum.amount, PastInstallmentColumnEnum.status,
            PastInstallmentColumnEnum.comment),

    ExpenseSearch("from Expense expense", null, null,
            "expense", "expense", ExpenseColumnEnum.paymentDate, "group by expense.id", "expense_search_export_file_name",
            ExpenseColumnEnum.number, ExpenseColumnEnum.expenseType, ExpenseColumnEnum.category, ExpenseColumnEnum.paymentDate,
            ExpenseColumnEnum.paymentMethod, ExpenseColumnEnum.paymentValue, ExpenseColumnEnum.tax, ExpenseColumnEnum.description,
            ExpenseColumnEnum.status),

    InstallmentSearch("from Installment installment", "join installment.sale sale", null,
            "installment", "installment", InstallmentColumnEnum.date, "group by installment.id", "installment_search_export_file_name",
            InstallmentColumnEnum.status, InstallmentColumnEnum.date,
            InstallmentColumnEnum.amount, InstallmentColumnEnum.paymentRequestBefore, InstallmentColumnEnum.paymentRequestAfter),

    PaymentSearch("from Payment payment", "join payment.sale sale", null,
            "payment", "payment", PaymentColumnEnum.date, "group by payment.id", "payment_search_export_file_name",
            PaymentColumnEnum.invoiceNumber, PaymentColumnEnum.scheduleDate, PaymentColumnEnum.date, PaymentColumnEnum.amount, PaymentColumnEnum.comment),

    PastInstallmentCountSearch("from Installment installment", "join installment.sale sale", null,
            "installment", "installment", null, "group by installment.id", "", InstallmentColumnEnum.numberOfPastInstallment),

    UserSearch("from User user", null, "left outer join user.userCredit userCredit", "user", "user", UserColumnEnum.name, "group by user.id", null,
            UserColumnEnum.name, UserColumnEnum.email, UserColumnEnum.limitedVisibility, UserColumnEnum.expirationDate);

    private String selectQueryFrom;
    private String selectQueryFromFilter;
    private String selectQueryFromNoFilter;
    private String principalAlias;
    private String modificationAlias;
    private ColumnDefinition defaultOrderByColumn;
    private String groupByPart;
    private String exportFileName;
    private ColumnDefinition[] columns;

    SearchMotorQueryEnum(String selectQueryFrom, String selectQueryFromFilter, String selectQueryFromNoFilter,
                         String principalAlias, String modificationAlias,
                         ColumnDefinition defaultOrderByColumn, String groupByPart,
                         String exportFileName,
                         ColumnDefinition... columns) {
        this.selectQueryFrom = selectQueryFrom;
        this.selectQueryFromFilter = selectQueryFromFilter;
        this.selectQueryFromNoFilter = selectQueryFromNoFilter;
        this.principalAlias = principalAlias;
        this.modificationAlias = modificationAlias;
        this.defaultOrderByColumn = defaultOrderByColumn;
        this.groupByPart = groupByPart;
        this.exportFileName = exportFileName;
        this.columns = columns;
    }

    public String getSelectQueryFrom() {
        return selectQueryFrom;
    }

    public String getSelectQueryFromFilter() {
        return selectQueryFromFilter;
    }

    public String getSelectQueryFromNoFilter() {
        return selectQueryFromNoFilter;
    }

    public String getPrincipalAlias() {
        return principalAlias;
    }

    public String getModificationAlias() {
        return modificationAlias;
    }

    public String getGroupByPart() {
        return groupByPart;
    }

    public ColumnDefinition[] getColumns() {
        return columns;
    }

    public ColumnDefinition getDefaultOrderByColumn() {
        return defaultOrderByColumn;
    }

    public String getExportFileName() {
        return exportFileName;
    }

    @Transient
    public List<ColumnDefinition> getNoTransientColumns() {
        List<ColumnDefinition> noTransientColumns = new ArrayList<ColumnDefinition>();
        for (ColumnDefinition column : columns) {
            if (!GenericTools.isEmpty(column.getHqlDefinition())) {
                noTransientColumns.add(column);
            }
        }
        return noTransientColumns;
    }

    @Transient
    public String getFromPart() {
        String fromPart = getSelectQueryFrom() + " " + getSelectQueryFromFilter() + " " + getSelectQueryFromNoFilter();
        return fromPart.replaceAll("null", "");
    }

    @Transient
    public String getFromPartWithMandatoryJoins() {
        String fromPartNoFilter = getSelectQueryFrom() + " " + getSelectQueryFromFilter();
        return fromPartNoFilter.replaceAll("null", "");
    }

}
